#ifndef _IMAGE_FORMAT_H_
#define _IMAGE_FORMAT_H_

#include <stdio.h>
#include <stdint.h>

typedef enum {
    IMAGE_FORMAT_RGB = 0,
    IMAGE_FORMAT_BGR,
    IMAGE_FORMAT_RGBA,
    IMAGE_FORMAT_BGRA,
    IMAGE_FORMAT_ARGB,
    IMAGE_FORMAT_ABGR,
} ImageFormat;

typedef struct {
    uint8_t r;
    uint8_t g;
    uint8_t b;
} ImagePointRGB;

typedef struct {
    uint8_t b;
    uint8_t g;
    uint8_t r;
} ImagePointBGR;

typedef struct {
    uint8_t r;
    uint8_t g;
    uint8_t b;
    uint8_t a;
} ImagePointRGBA;

typedef struct {
    uint8_t b;
    uint8_t g;
    uint8_t r;
    uint8_t a;
} ImagePointBGRA;

typedef struct {
    uint8_t a;
    uint8_t r;
    uint8_t g;
    uint8_t b;
} ImagePointARGB;

typedef struct {
    uint8_t a;
    uint8_t b;
    uint8_t g;
    uint8_t r;
} ImagePointABGR;

typedef union {
    uint8_t *addr;
    uint32_t *addr32;
    ImagePointRGB *rgb;
    ImagePointBGR *bgr;
    ImagePointRGBA *rgba;
    ImagePointBGRA *bgra;
    ImagePointARGB *argb;
    ImagePointABGR *abgr;
} ImageMem;

typedef struct {
    uint32_t width;
    uint32_t height;
    uint32_t pb; // 每像素字节数
    uint32_t size;
    ImageFormat format;
} ImageInfo;

typedef struct {
    ImageInfo info;
    ImageMem mem;
} Image;

//胶圈,顾名思义,用于逐帧动画
//基于长条状的image,在不同时候选取不同位置的内存
struct Film {
    int32_t block = 1;
    int32_t width = 0;
    int32_t height = 0;
    int32_t size = 0;
    int32_t index = 0;
    Image *image = NULL;

    //装载image,默认分块数1
    void Init(Image *image, int32_t block = 1) {
        this->image = image;
        this->block = block < 1 ? 1 : block;
        width = image->info.width;
        height = image->info.height / this->block;
        size = image->info.size / this->block;
        index = 0;
    }
    //设置默认序号
    void SetIndex(int32_t index) {
        this->index = index < 0 ? 0 : (index % block);
    }
    void NextIndex() {
        this->index = (this->index + 1) % block;
    }
    //取默认地址
    uint8_t *Addr() {
        if (!image)
            return NULL;
        return image->mem.addr + size * index;
    }
    uint32_t *Addr32() {
        return (uint32_t*)Addr();
    }
    //取指定序号地址
    uint8_t *Addr(int32_t index) {
        if (!image)
            return NULL;
        return image->mem.addr + size * index;
    }
    uint32_t *Addr32(int32_t index) {
        return (uint32_t*)Addr(index);
    }
};

//创建图像和内存回收
Image ImageCreate(uint32_t width, uint32_t height, ImageFormat format);
void ImageDestory(Image image);

//对image缩放+转换格式后返回新的image
Image ImageTranslate(Image image, uint32_t width, uint32_t height, ImageFormat format);

//清空图像
//1. color格式 0x12345678 其中 78蓝色 56绿色 34红色 12透明度(越大越透明)
//2. 下面见到的 color 都是这个格式
void ImageClear(Image image, uint32_t color);

//像素写: 会考虑透明度叠加效果
void ImageWrite(Image image, int32_t x, int32_t y, uint32_t color);
void ImageWrite(Image image, int32_t x, int32_t y, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
//plane缩放到w*h后写到image的(x,y)位置
void ImageWrite(Image image, int32_t x, int32_t y, uint32_t width, uint32_t height, Image plane);
void ImageWrite(Image image, int32_t x, int32_t y, uint32_t width, uint32_t height, Film plane, int32_t index);

//像素覆盖: Write会考虑透明度处理,而Cover则是直接覆盖
void ImageCover(Image image, int32_t x, int32_t y, uint32_t color);
void ImageCover(Image image, int32_t x, int32_t y, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
void ImageCover(Image image, int32_t x, int32_t y, uint32_t width, uint32_t height, Image plane);
void ImageCover(Image image, int32_t x, int32_t y, uint32_t width, uint32_t height, Film plane, int32_t index);

#endif // _IMAGE_FORMAT_H_
